﻿package appLoader.dictionaries {
	
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.text.TextField;
	
	import appLoader.data.MasterConfig;
	import appLoader.data.HashTable;
	import appLoader.data.HashTable3;
	import appLoader.dictionaries.Dictionary;
	import appLoader.dictionaries.DictionaryManager;
	import errors.SingletoneError;
	import text.TextFitter;
	import text.TextFitterSettings;
	
	import toolTips.ToolTipCreator;
	
	public class DictionaryManager extends EventDispatcher {
		
		private var _currentLang	:String;
		private var _currentURLPf	:String; // url lang prefix: 'br' to 'pt-br', 'en' to 'en-us', 'es' to 'es-es'.
		private var _xmlUrl			:String;
		private var _table			:HashTable3;
		private var _languages		:HashTable3;
		private var _langNames		:Array;
		private var _dictionary		:Dictionary;
		private var _fitter			:TextFitter;
		private var _clipsManager	:DictionaryMovieClips;
		private var _config			:MasterConfig;
		
		private static var _instance:DictionaryManager;
		private static var _allowInstance:Boolean = true;;
		
		static public const ON_DICTIONARY_MANAGER_LOADED:String = 'ON_DICTIONARY_MANAGER_LOADED';
		
		public function DictionaryManager() {
			if (_allowInstance) {
				super();
				this._table 		= new HashTable3();
				this._languages		= new HashTable3();
				this._currentLang	= "en-us";
				this._fitter		= new TextFitter();
				this._clipsManager	= new DictionaryMovieClips();
				this._config		= MasterConfig.gett();
				_allowInstance		= false;
			} else {
				throw new SingletoneError("DictionaryManager attempt to instantiate twice");
			}
		}
		
		static public function gett():DictionaryManager {
			if (_instance == null) _instance = new DictionaryManager();
			return _instance;
		}
		
		public function init(url:String, lang:String):void {
			this._dictionary 		= Dictionary.gett();
			this._currentLang 		= lang;
			this._dictionary.addEventListener(Dictionary.ON_DICTIONARY_LOADED, loaded);
			// Criar os idiomas no Dictionary:
			this.createLanguages();
			this._dictionary.loadXML(url);
			this._clipsManager.currentLanguage = lang;
		}
		
		private function createLanguages():void{
			var tt:int = this._config.table.getArrayProperty('languages').length;
			for (var i:int = 0; i < tt; i++) {
				this._dictionary.createLanguage(this._config.table.getArrayProperty('languages')[i], this._config.table.getArrayProperty('dictioNodes')[i], this._config.table.getArrayProperty('urlLangPrefixes')[i]);
			}
		}
		
		private function loaded(e:Event):void {
			// setar o idioma inicial:
			this._dictionary.lang = this._currentLang;
			this.dispatchEvent(new Event(ON_DICTIONARY_MANAGER_LOADED));
		}
		
		public function associate(textField:TextField, dictioKey:String, style:TextFitterSettings = null, tCase:String = "UpperCase"):void {
			//trace('associate ', textField.parent.name, '.', textField.name, dictioKey);
			if (style == null) style = new TextFitterSettings(textField.x, textField.y, Number(textField.defaultTextFormat.size), textField.height, tCase);
			this._table.put(textField, dictioKey, style);
			// já exibir o texto inicial:
			this._fitter.fit(textField, this._dictionary.getText(dictioKey), style);
		}
		
		public function associateToolTip(tooltip:ToolTipCreator, dictioKey:String):void {
			//trace('associate ', textField.parent.name, '.', textField.name, dictioKey);
			this._table.put(tooltip.newText, dictioKey);
			tooltip.inputText=_dictionary.getText(dictioKey);
			tooltip.tipEnabled=true;
		}
		
		public function associateClip(mc:MovieClip):void {
			this._clipsManager.insertClip(mc);
		}
		
		private function rewrite(language:String):void {
			this._currentLang 		= language;
			this._dictionary.lang 	= language;
			this._clipsManager.changeTo(language);
			var tt:int 				= this._table.length();
			while (tt--) {
				var tf:TextField 				= TextField(this._table.getKeyByIndex(tt));
				var dictKey:String 				= String(this._table.getValueByIndex(tt));
				var style:TextFitterSettings	= TextFitterSettings(this._table.getValue2ByIndex(tt));
				var txt:String 					= String(this._dictionary.getText(dictKey));
				try {
					if (tf == null || style == null || txt == null) throw new Error("Dictionary null params");
					this._fitter.fit(tf, txt, style);
				} catch (e:Error) {
					//trace(e);
					//trace(tf + style + txt);
				}
			}
		}
		
		/**
		 * Coloca os clips que foram associados durante a montagem da interface no
		 * idioma atual.
		 *
		 * @param	language -> idioma desejado.
		 */
		public function forceChangeLanguage(language:String):void {
			if (language == null) return;
			this.changeLanguage(language);
		}
		
		public function changeLanguage(language:String):void {
			if (this._currentLang == language || language == null) return;
			this._dictionary.lang = language;
			this.rewrite(language);
		}
		
		public function get currentLang():String { return _currentLang; }
		public function get dictionary():Dictionary { return _dictionary; }
		
		override public function toString():String {
			var s:String = "[ DictionayManager ]\n";
			s += "lang: " + this._currentLang + "\n";
			return s;
		}
		
	}
	
}
